package luccy.behavior;

import luccy.desc.ClassDesc;
import luccy.desc.ConstructorDesc;
import luccy.desc.Desc;
import luccy.desc.MethodDesc;
import luccy.desc.PropertyDesc;
import luccy.registry.Registry;
import luccy.util.AssertionUtil;

public class Awares {

	public static void prepareAware(Behavior behavior, Registry registry,
			Desc... descs) {
		AssertionUtil.assertNotNull(behavior);
		if (behavior instanceof RegistryAware) {
			((RegistryAware) behavior).setRegistry(registry);
		}
		if (descs == null || descs.length == 0) {
			return;
		}
		for (Desc desc : descs) {
			if (shouldProcessClassDesc(desc, behavior)) {
				((ClassDescAware) behavior).setClassDesc((ClassDesc) desc);
			} else if (shouldProcessConstrucorDesc(desc, behavior)) {
				((ConstructorDescAware) behavior)
						.setConstructorDesc((ConstructorDesc) desc);
			} else if (shouldProcessPropertyDesc(desc, behavior)) {
				((PropertyDescAware) behavior)
						.setPropertyDesc((PropertyDesc) desc);
			} else if (shouldProcessMethodDesc(desc, behavior)) {
				((MethodDescAware) behavior).setMethodDesc((MethodDesc) desc);
			}
		}
	}

	private static boolean shouldProcessClassDesc(Desc desc, Behavior behavior) {
		return desc instanceof ClassDesc && behavior instanceof ClassDescAware;
	}

	private static boolean shouldProcessConstrucorDesc(Desc desc,
			Behavior behavior) {
		return desc instanceof ConstructorDesc
				&& behavior instanceof ConstructorDescAware;
	}

	private static boolean shouldProcessPropertyDesc(Desc desc,
			Behavior behavior) {
		return desc instanceof PropertyDesc
				&& behavior instanceof PropertyDescAware;
	}

	private static boolean shouldProcessMethodDesc(Desc desc, Behavior behavior) {
		return desc instanceof MethodDesc
				&& behavior instanceof MethodDescAware;
	}

}
